/*
 * fitness.h
 *
 * Copyright (C) 2008, 2009
 *
 * Lukasz Bieniasz-Krzywiec
 * Dariusz Leniowski
 */

#ifndef FITNESS_H_
#define FITNESS_H_

#include "../config.h"

#include "osobnik.h"

extern osobnik  **populacja;
extern int      *osobnik_fitness;
extern int      *fitness_osobnik;
extern int       rodz[MAX_RODZAJOW+1];
extern int       RODZAJE_REF[MAX_RODZAJOW+1];

class fitness {
public:
  fitness() {}
  virtual ~fitness() {}

  /*
   * Przelicz przystosowanie wszystkich osobnikow (implementacja
   * bazowa to fitness staly = 1.0 dla wszystkich osobnikow)
   * Zalozenia:
   * - Populacja znajduje sie w globalnej tablicy populacja rozmiaru N
   * Wynik:
   * - Pola fitness w osobnikach zostaly uaktualnione
   * - Permutacje fitness_osobnik, osobnik_fitness zostaly uaktualnione
   */
  virtual void oblicz();

  /* Komparator pomocniczy dla funkcji sort */
  static bool cmp(int a, int b);

  /* Permutuje losowo tablice zaczynajaca sie w a
   * o rozmiarze b-a 
   */
  static void shuffle(int *a, int *b);

  /* Permutuje losowo osobniki o takim samym fitnessie */
  static void randomize();

  /* Wylaczenie wspolnego kodu:
   * - posortowanie wzgledem fitnessu
   * - przetasowanie w ramach tego samego fitnessu
   * - odwrocenie permutacji fitness_osobnik
   *   do osobnik_fitness
   */
  static void sort_randomize_reverse();
};

class fitness_ostatnia_wyplata : public fitness {
public:
  fitness_ostatnia_wyplata();
  ~fitness_ostatnia_wyplata();

  /*
   * Przelicz przystosowanie wszystkich osobnikow
   * Dodatkowe zalozenia:
   * - Kazdy osobnik mial jakas wyplate
   */
  void oblicz();
};

/* suma wyplat podzielona przez stopien (sume wag krawedzi wychodzacych) */
class fitness_ostatnia_wyplata_znormalizowana : public fitness {
public:
  fitness_ostatnia_wyplata_znormalizowana();
  ~fitness_ostatnia_wyplata_znormalizowana();
  void oblicz();
};

/* liczebnosc rodzaju do ktorego nalezy osobnik */
class fitness_liczebnosc_rodzaju : public fitness {
public:
  fitness_liczebnosc_rodzaju();
  ~fitness_liczebnosc_rodzaju();
  void oblicz();
};

/* suma wyplat osobnikow z danego rodzaju */
class fitness_wyplata_rodzaju : public fitness {
public:
  fitness_wyplata_rodzaju();
  ~fitness_wyplata_rodzaju();
  void oblicz();
};

/* suma znormalizowanych wyplat osobnikow z danego rodzaju */ 
class fitness_wyplata_znormalizowana_rodzaju : public fitness {
public:
  fitness_wyplata_znormalizowana_rodzaju();
  ~fitness_wyplata_znormalizowana_rodzaju();
  void oblicz();
};


#endif /* FITNESS_H_ */
